import {
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
  Mesh,
  MeshBasicMaterial,
  AxesHelper,
  Color,
  GridHelper,
  ExtrudeBufferGeometry,
  Group,
  Shape,
  DoubleSide,
  SphereGeometry,
  MeshStandardMaterial,
  PointLight,
  PlaneGeometry,
  TextureLoader,
  BoxGeometry,
  RepeatWrapping,
} from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

let camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer;
let pointLight: PointLight;

init();
animate();

function init() {
  camera = new PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    1,
    1000
  );
  camera.position.set(15, 15, -15);
  scene = new Scene();

  let lightGeo = new SphereGeometry(0.4);
  let lightMat = new MeshStandardMaterial({
    emissive: "#fff",
    emissiveIntensity: 1,
    color: "#000",
  });
  let lightMesh = new Mesh(lightGeo, lightMat);

  pointLight = new PointLight("#fff", 1);
  pointLight.position.set(0, 15, 0);
  pointLight.castShadow = true;
  pointLight.add(lightMesh);
  scene.add(pointLight);

  let groundMat = new MeshStandardMaterial({
    roughness: 0.8,
    color: 0xffffff,
    metalness: 0.2,
    bumpScale: 0.0005,
  });

  new TextureLoader().load(
    require("../static/textures/hardwood2_diffuse.jpg").default,
    (map) => {
      map.wrapS = RepeatWrapping;
      map.wrapT = RepeatWrapping;
      map.anisotropy = 4;
      map.repeat.set(10, 24);
      groundMat.map = map;
      groundMat.needsUpdate = true;
    }
  );
  new TextureLoader().load(
    require("../static/textures/hardwood2_bump.jpg").default,
    (map) => {
      map.wrapS = RepeatWrapping;
      map.wrapT = RepeatWrapping;
      map.anisotropy = 4;
      map.repeat.set(10, 24);
      groundMat.bumpMap = map;
      groundMat.needsUpdate = true;
    }
  );
  new TextureLoader().load(
    require("../static/textures/hardwood2_roughness.jpg").default,
    (map) => {
      map.wrapS = RepeatWrapping;
      map.wrapT = RepeatWrapping;
      map.anisotropy = 4;
      map.repeat.set(10, 24);
      groundMat.roughnessMap = map;
      groundMat.needsUpdate = true;
    }
  );

  let groundGeo = new PlaneGeometry(100, 100);
  let groundMesh = new Mesh(groundGeo, groundMat);
  groundMesh.rotateX(-Math.PI / 2);
  groundMesh.receiveShadow = true;
  scene.add(groundMesh);

  new TextureLoader().load(
    require("../static/textures/earth_atmos_2048.jpg").default,
    (map) => {
      let earthGeo = new SphereGeometry(4, 100, 100);
      let earthMat = new MeshStandardMaterial({ color: "#fff", map: map });
      let earthMesh = new Mesh(earthGeo, earthMat);
      earthMesh.castShadow = true;
      earthMesh.position.set(10, 4, 10);
      scene.add(earthMesh);
    }
  );

  new TextureLoader().load(
    require("../static/textures/brick_diffuse.jpg").default,
    (map) => {
      let wallGeo = new BoxGeometry(5, 5, 5);
      let wallMat = new MeshStandardMaterial({ color: "#fff", map: map });
      let wallMesh = new Mesh(wallGeo, wallMat);
      wallMesh.castShadow = true;
      wallMesh.position.set(10, 2.5, -10);
      scene.add(wallMesh);
    }
  );

  renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.shadowMap.enabled = true;
  // renderer.physicallyCorrectLights = true;
  document.body.appendChild(renderer.domElement);

  let control = new OrbitControls(camera, renderer.domElement);
  // renderer.render(scene, camera);
}

function animate() {
  requestAnimationFrame(animate);

  const time = Date.now() * 0.0005;
  pointLight.position.y = Math.cos(time) * 20 + 25;
  renderer.render(scene, camera);
}
